/*
 * Licensed to the Tai Ping Jin Ke
 *
 * Copyright (c) 2022 .
 * All rights reserved.
 * 项目名称：呼叫中心-业务逻辑层-工作台-接口实现
 * 版权说明：本软件属太平金融科技服务(上海)有限公司所有，在未获得太平金融科技服务(上海)有限公司正式授权情况下，任何企业和个人，不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。
 */
package com.taiping.cc.platform.service.impl;

import com.google.common.collect.ImmutableMap;
import com.taiping.cc.application.constant.cache.CacheKeyEnum;
import com.taiping.cc.application.constant.minio.BucketEnum;
import com.taiping.cc.application.tools.DownloadUtils;
import com.taiping.cc.platform.base.BaseService;
import com.taiping.cc.platform.service.PlatformService;
import com.taipingframework.boot.web.response.result.ApiResult;
import com.taipingframework.boot.web.response.status.ApiStatusEnum;
import com.taipingframework.utility.exception.ServiceException;
import com.taipingframework.utility.unid.AppGenKey;
import io.minio.http.Method;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
@RequestMapping("/service/platform")
public class PlatformServiceImpl extends BaseService implements PlatformService {
//CHECKSTYLE:OFF

    private final AppGenKey appGenKey;

    @Override
    public ApiResult<TreeMap<String, String>> queryForActionDataList() throws ServiceException {
        TreeMap<String, String> resultMap = ImmutableMap.of("key1", "王八1", "key2", "癞蛤蟆2")
                .entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> newValue, TreeMap::new));

        try {
            log.trace("trace日志测试");
            log.debug("debug日志测试");
            log.info("info日志测试");
            log.warn("warn日志测试");
            log.error("error日志");

            cacheHandler.setValue(CacheKeyEnum.SESSION_LOGIN_TIME, LocalDateTime.now());

            return ApiResult.<TreeMap<String, String>>build()
                    .setStatus(ApiStatusEnum.SUCCESS)
                    .setResult(resultMap);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public ApiResult<ArrayList<String>> unidList() throws ServiceException {
        try {
            // 分布式全局唯一ID生成
            ArrayList<String> list = new ArrayList<>();
            for (int i = 0; i < 200; i++) {
                list.add(appGenKey.getUniqueKey().toString());
            }
            return ApiResult.<ArrayList<String>>build()
                    .setStatus(ApiStatusEnum.SUCCESS)
                    .setResult(list);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public ApiResult<Boolean> redisLock() throws ServiceException {
        try {
            CountDownLatch countDownLatch = new CountDownLatch(15);
            // 分布式锁演示，保证 ”幂等性“
            RedisLockTest threadTest = new RedisLockTest(countDownLatch, cacheHandler);
            for (int i = 0; i < 15; i++) {
                new Thread(threadTest, "thread_app_" + i).start();
            }
            countDownLatch.await();

            return ApiResult.<Boolean>build()
                    .setStatus(ApiStatusEnum.SUCCESS)
                    .setResult(true);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    @Override
    public ApiResult<Boolean> zkLock() throws ServiceException {
        try {
            CountDownLatch countDownLatch = new CountDownLatch(15);
            // 分布式锁演示，保证 ”幂等性“
            ZookeeperLockTest threadTest = new ZookeeperLockTest(countDownLatch);
            for (int i = 0; i < 15; i++) {
                new Thread(threadTest, "thread_app_" + i).start();
            }
            countDownLatch.await();

            return ApiResult.<Boolean>build()
                    .setStatus(ApiStatusEnum.SUCCESS)
                    .setResult(true);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    /**
     * minio文件上传服务
     */
    @Override
    public ApiResult<HashMap<String, String>> uploadAttachment(MultipartFile file) throws ServiceException {
        try {
            fileService.uploadFileObject(file.getInputStream(), file.getOriginalFilename(), BucketEnum.BUCKET_PLATFORM);
            String objectUrl = fileService.getObjectUrl(file.getOriginalFilename(), BucketEnum.BUCKET_PLATFORM, Method.GET, null);
            HashMap<String, String> result = new HashMap<>();
            result.put("file", file.getOriginalFilename());
            result.put("url", objectUrl);

            return ApiResult.<HashMap<String, String>>build()
                    .setStatus(ApiStatusEnum.SUCCESS)
                    .setResult(result);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

    /**
     * minio文件下载服务
     */
    @Override
    public ResponseEntity<Resource> downloadAttachment(String objectName) throws ServiceException {
        try {
            String objectUrl = fileService.getObjectUrl(objectName, BucketEnum.BUCKET_PLATFORM, Method.GET, null);
            return DownloadUtils.readResourceData(objectUrl, objectName);
        } catch (Exception e) {
            throw new ServiceException(e);
        }
    }

//CHECKSTYLE:ON
}
